package gupao.concurrency.threads;

import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;

@Slf4j
public class ThreadInterruptDemo {

    public static void main(String[] args){
//        isInterruptedTest();
//        interruptedTest();
        interruptedExceptionTest2();
    }



    static void interruptedTest(){
        Thread.currentThread().interrupt();
        log.info("第一次调用myThread.interrupted(),返回值：{}",
                Thread.interrupted()
        );
        log.info("第一次调用myThread.interrupted(),返回值：{}",
                Thread.interrupted()
        );
        log.info("===========end=============");
    }

    static void isInterruptedTest() {
        AtomicLong l = new AtomicLong(0);
        Thread myThread = new Thread(() -> {
            for(int i = 0; i < Integer.MAX_VALUE; i++){
                Double x = Math.sqrt(i);
                l.set(x.longValue() * i + i);
            }
            log.info("{} will be finished.", Thread.currentThread().getName());
        });
        myThread.setDaemon(true);
        myThread.start();
        myThread.interrupt();
        log.info("第一次调用myThread.isInterrupted(),返回值：{}",
                myThread.isInterrupted()
        );
        log.info("第一次调用myThread.isInterrupted(),返回值：{}",
                myThread.isInterrupted()
        );
        log.info("===========end=============");
    }

    static volatile boolean flag = true;
    static void interruptedExceptionTest(){
        Thread t = new Thread(() -> {
            while(flag){
                try {
                    Thread.sleep(1000);
                    log.info("{} is running..", Thread.currentThread().getName());
                } catch (InterruptedException e) {
                    log.error("{} receive InterruptedException", Thread.currentThread().getName());
                    flag = false; //线程被中断了，设置停止运行标识
                }
            }
            log.info("{} will be finished soon.", Thread.currentThread().getName());
        });

        t.start();
        interruptSubThreadAndComplete(t);
    }

    private static void interruptSubThreadAndComplete(Thread subThread){
        Utils.sleepIgnoreExp(5000);//主线程sleep 5s
        subThread.interrupt();
        Utils.sleepIgnoreExp(2000);//主线程sleep 2s, 等待 t 中断后结束运行
        log.info("{} completed.", Thread.currentThread().getName());
    }

    static void interruptedExceptionTest2(){
        Runnable r = () -> {
            while(!Thread.currentThread().isInterrupted()){
                try{
                    //do something for business
                    Thread.sleep(1000);
                    log.info("{} is running..", Thread.currentThread().getName());
                }catch (InterruptedException e){
                    log.error("{} receive InterruptedException, it will stop.", Thread.currentThread().getName());
                    log.info("{}: {} ", Thread.currentThread().getName(), Thread.currentThread().isInterrupted());
                    Thread.currentThread().interrupt(); //重设中断标识,退出while循坏
                }
            }
            log.info("{} finished.", Thread.currentThread().getName());
        };

        Thread t = new Thread(r);
        t.start();
        interruptSubThreadAndComplete(t);
    }
}
